/**
 * 
 */
package jvs.tea.html;

import java.net.URI;

import x.java.io.File;
import x.java.tea.InputStreamInjector;

/**
 * @author qiangli
 * 
 */
public class FileTypeTemplateInputStream extends FileObjectInputStream {
	private static final String TPL_EXT = ".htm";
	private static final String[][] FILE_MENU = new String[][] {
			{ "v-bin-shell:///bin/delete", "", "Delete" },
			{ "v-bin-shell:///bin/rename", "", "Rename" },
			{ "v-bin-shell:///bin/send", "", "Share" } };

	// mime-type to template mapping
	private static final String[][] MIME_TYPES = { { "mp3", "audio" },
			{ "3gpp", "audio" }, { "mp4", "audio" }, { "m4a", "audio" },
			{ "mid", "audio" }, { "xmf", "audio" }, { "mxmf", "audio" },
			{ "imy", "audio" }, { "wma", "audio" }, { "wav", "audio" },
			{ "ogg", "audio" },

			{ "jpg", "image" }, { "jpe", "image" }, { "jpeg", "image" },
			{ "gif", "image" }, { "png", "image" }, { "bmp", "image" },

			{ "mp4", "video" }, { "3gp", "video" }, { "mpe", "video" },
			{ "mpeg", "video" }, { "mpg", "video" }, { "wmv", "video" },

			{ "txt", "text" }, { "rc", "text" }, { "properties", "text" },

			{ "htmf", "htmf" } };

	private static final String[][] TEXTFILE_ACTIONS = new String[][] { {
			"edit", "editor.png", "Edit" } };
	private long maxbyte = 1024;

	public FileTypeTemplateInputStream(URI context, URI asset, File.Info file) {
		super(context, asset, file);
		init();
	}

	private void init() {
		final String path = file.getPath();
		//
		addInjector("breadcrumb", makeBreadcrumbs(root, parent(path), true));

		String tpl = getTempateName(path);
		if (tpl == null) {
			tpl = "unknown";
		}
		//
		if (tpl.equals("text")) {
			setInputStream(getClass().getResourceAsStream(
					Constant.TEMPLATE_DIR + "text" + TPL_EXT));
			try {
				addInjector("filecontent", new InputStreamInjector(file
						.getInputStream()));
				String more = file.length > maxbyte ? "..." : "";
				addInjector("filecontent.more", more);
			} catch (Exception e) {
				e.printStackTrace();
			}
		} else if (tpl.equals("htmf")) {
			setInputStream(getClass().getResourceAsStream(
					Constant.TEMPLATE_DIR + "htmf" + TPL_EXT));
			try {
				addInjector("filecontent", new InputStreamInjector(file
						.getInputStream()));
				String more = file.length > maxbyte ? "..." : "";
				addInjector("filecontent.more", more);
			} catch (Exception e) {
				e.printStackTrace();
			}
		} else if (tpl.equals("image") || tpl.equals("audio")
				|| tpl.equals("video")) {
			setInputStream(getClass().getResourceAsStream(
					Constant.TEMPLATE_DIR + tpl + TPL_EXT));
		} else {
			setInputStream(getClass().getResourceAsStream(
					Constant.TEMPLATE_DIR + "unknown" + TPL_EXT));
		}
		//
		final StringBuilder sb = new StringBuilder();

		// menu
		menu(sb, FILE_MENU, path);
		addInjector("menu", sb.toString());

		// action - text only for now
		if (tpl.equals("text") || tpl.equals("htmf")) {
			sb.setLength(0);
			smartaction(sb, TEXTFILE_ACTIONS, path);
			addInjector("actionbar", sb.toString());
		}
		//
		addInjector("post", new InputStreamInjector(
				new CommentTemplateInputStream(context, asset, file)));
	}

	private String parent(String path) {
		// path is a file
		int idx = path.lastIndexOf('/');
		if (idx > 0) {
			return path.substring(0, idx);
		}
		return path;
	}

	private String getTempateName(String name) {
		// lookup by ext
		// String name = file.getName();
		String type = lookup(name);
		if (type != null) {
			return type;
		}
		// we can check this first, but we want a quicker return for known types
		if (name.endsWith(File.LINK_EXT)) {
			int idx = name.length() - File.LINK_EXT.length();
			type = lookup(name.substring(0, idx));
			if (type != null) {
				return type;
			}
		}
		// lookup by type
		String ctype = file.getContentType();
		if (ctype != null) {
			int idx = ctype.indexOf("/");
			return (idx == -1) ? ctype : ctype.substring(0, idx);
		}
		return null;
	}

	private String lookup(String name) {
		int idx = name.lastIndexOf('.');
		if (idx == -1) {
			return null;
		}
		String ext = name.substring(idx + 1).toLowerCase();
		for (int i = 0; i < MIME_TYPES.length; i++) {
			if (ext.equals(MIME_TYPES[i][0])) {
				return MIME_TYPES[i][1];
			}
		}
		return null;
	}
}
